home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctj1186.arc
/
PRF.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-09-19
|
12KB
|
293 lines
;USER-CHANGEABLE CONSTANTS
;NUMBER OF BYTES IN DATA TABLE (F000 = 60K)
Table_Size EQU 0F000H
;NUMBER OF TICKS BETWEEN JUMPS TO ORIGINAL CLOCK INTERRUPT HANDLER
; = CLOCK SPEEUP FACTOR
Number_Of_Ticks EQU 1
;OTHER CONSTANTS
;MAXIMUM VALUE OF COUNTDOWN FOR TIMER 0 INTERRUPT
Max_Timer_Count EQU 0FFFFH
;NEW VALUE OF COUNTDOWN FOR TIMER 0 INTERRUPT
New_Timer_Count EQU Max_Timer_Count / Number_Of_Ticks
PSP SEGMENT PUBLIC
ASSUME CS:PSP, DS:PSP, ES:PSP, SS:PSP
ORG 100H ;COM FILE!
;------------------------------------------------------------------
; profiler kernel ;
; ;
; tricks: ;
; 1. program executes file 'subject.com' - which may be ;
; a com or exe file. use a batch file to copy subject ;
; file to 'subject.com'. ;
; 2. run with 'prf fn1 fn2', where 'fn1' and 'fn2' ;
; are the parameters you would have typed if you had been ;
; running the subject code itself. this allows ;
; copying the formatted file info from the profiler's ;
; psp into the psp for the subject code. ;
;-----------------------------------------------------------------;
PRF PROC FAR
MOV SP, OFFSET END_STACK ; set top of stack to
; internal area
CALL FREE_MEM ; free unused memory
CALL REPLACE_TIMER ; replace timer/interrupt
CALL EXEC_SUBJECT ; execute & collect data
CALL RESTORE_TIMER ; restore timer/interrupt
CALL EXEC_PRINT ; execute data reduction
; and printout program
INT 20H ; terminate
PRF ENDP
;-------------------------------------------------------------------
; returns unused memory to dos ;
;-------------------------------------------------------------------
FREE_MEM PROC NEAR
MOV BX, OFFSET EOM ; offset of top of memory
MOV CL, 4 ; shift count
SHR BX, CL ; divide by 16 to get
; number of paragraphs
ADD BX, 1 ; in case not multiple of 16
MOV AH, 4AH ; code for memory release
INT 21H ; do the shrink
JNC SUCCESS ; go on if carry flag
; is zero (no error)
MOV AH, 9 ; code for print string
MOV DX, OFFSET MEM_ERR_STRNG
; error message
INT 21H ; dos function call for print
INT 20H ; end if error returned
SUCCESS: RET ; return
FREE_MEM ENDP
;-----------------------------------------------------------------;
; run subject program under profiler ;
;-----------------------------------------------------------------;
EXEC_SUBJECT PROC NEAR
MOV AX, CS ; to set seg registers
MOV DS, AX ; ds:dx point to asciiz
; string with name of
MOV DX, OFFSET SUBJECT_NAME ; file to execute
MOV ES, AX ; es:bx point to
MOV BX, OFFSET EXEC_PARAMS ; parameter block
MOV CX, CS:[2CH] ; set segment address
MOV ENVIRON_SEG, CX ; of passed environment
MOV COMMND_OFS, 80H ; set offset and segment
MOV COMMND_SEG, CS ; of passed command line
MOV FCB1_OFS, 5CH ; set offset and segment
MOV FCB1_SEG, CS ; of unopened fcb1
MOV FCB2_OFS, 6CH ; set offset and
MOV FCB2_SEG, CS ; segment of unopened fcb2
MOV AX, 4B00H ; set ax register for load
; and execute dos call
MOV ACCUM_FLAG, 1 ; turn on address accumulation
; flag
MOV SAV_SP, SP ; save stack pointer
INT 21H ; do interrupt
MOV AX, CS ; restore
MOV ES, AX ; segment registers
MOV DS, AX ; and stack
MOV SS, AX
MOV SP, SAV_SP
MOV ACCUM_FLAG, 0 ; turn off address
; accumulation flag
RET
EXEC_SUBJECT ENDP
;--------------------------------------------------------------
EXEC_PRINT PROC NEAR
MOV AX, CS ; to set seg registers
MOV ES, AX
MOV DS, AX
MOV SS, AX
MOV DS, AX ; ds:dx point to
MOV DX, OFFSET PRINT_NAME ; asciiz string with
; name of file to
; execute
; move segment and offset of data into words 0-3 of cs:5ch (fcb1)
MOV AX, OFFSET DATA_TABLE ; offset of data
MOV BX, 5CH ; offset into cseg
MOV CS:[BX], AX ; move offset into fcb1
MOV AX, CS ; cs to ax
MOV CS:[BX+2], AX ; move cs into fcb1
; divide table offset by 4 to get number of samples
MOV CL, 2 ; shift count to cl
SHR TABLE_OFS, CL ; shift to divide
MOV ES, AX ; es:bx points to
MOV BX, OFFSET EXEC_PARAMS ; parameter block
MOV CX, CS:[2CH] ; turn off address
MOV ENVIRON_SEG, CX ; accumulation flag
MOV COMMND_OFS, 80H ; set offset and segment
MOV COMMND_SEG, CS ; of passed command line
MOV FCB1_OFS, 5CH ; set offset and segment
MOV FCB1_SEG, CS ; to unopened fcb1
MOV FCB2_OFS, 6CH ; set offset and segment
MOV FCB2_SEG, CS ; of unopened fcb2
MOV SAV_SP, SP ; save stack pointer
MOV AX, 4B00H
INT 21H ;dos function call
MOV AX, CS
MOV DS, AX ; restore segment registers
MOV ES, AX ; and stack pointer
MOV SS, AX
MOV SP, SAV_SP
RET
EXEC_PRINT ENDP
;-----------------------------------------------------------------
; replaces the existing timer 0 countdown value and the ;
; existing interrupt 8 ;
;-----------------------------------------------------------------
REPLACE_TIMER PROC NEAR
PUSH DS ; save data segment
CLI ; disable maskable interrupts
; replace timer 0 countdown to (maybe) speed up timer
MOV AL, 36H ; timer 0, mode 3, will send
; lsb, msb
OUT 43H, AL ; write mode control word
; to timer
MOV BX, New_Timer_Count
; new countdown value
MOV AL, BL ; lsb of new_timer_count
OUT 40H, AL ; write lsb to timer 0
MOV AL, BH ; msb of new_timer_count
OUT 40H, AL ; write msb to timer 0
; replace existing interrupt 8
XOR AX, AX ;0 to ax
MOV DS, AX ; seg for interrupt vectors
MOV AX, DS:[20H] ; contents of 0:20 to ax
MOV CS:OLD_OFS, AX ; save in old_ofs
MOV AX, DS:[22H] ; contents of 0:22 to ax
MOV CS:OLD_SEG, AX ; save in old_seg
MOV DS:[20H], OFFSET NEW_TIMER ; new offset
MOV DS:[22H], CS ; new seg
STI ; enable maskable interrupts
POP DS ; restore data segment
RET ; return
REPLACE_TIMER ENDP
;-------------------------------------------------------------------;
; restores the original interrupt 8 and the timer 0 ;
; countdown to the power-up value ;
;-------------------------------------------------------------------;
RESTORE_TIMER PROC NEAR
CLI ; disable maskable interrupts
; restore interrupt 8
MOV AX, 0 ; 0 to ax
MOV DS, AX ; segment for interrupt
; vectors
MOV AX, CS:OLD_OFS ; old_ofs to ax
MOV DS:[20H], AX ; contents of ax to 0:20
MOV AX, CS:OLD_SEG ; old_seg to ax
MOV DS:[22H], AX ; contents of ax to 0:22
; restore timer 0 countdown to power-up value
MOV AL, 36H ; timer 0, mode 3, will
; send lsb, msb
OUT 43H, AL ; write mode control word
; to timer
MOV AL, 0 ; lsb and msb of 0
OUT 40H, AL ; write lsb to timer 0
OUT 40H, AL ; write msb to timer 0
STI ; enable maskable interrupts
RET ; return
RESTORE_TIMER ENDP
;-------------------------------------------------------------------;
; replaces old timer interrupt. accumulates data if ;
; accum_flag is set, and jumps to previous int 8 if ;
; timing is appropriate ;
;-------------------------------------------------------------------;
NEW_TIMER PROC NEAR
CMP CS:ACCUM_FLAG, 0 ; check to see if
; we accumulate
JE DO_OLD_INT8? ; skip accumulate if 0
CALL ACCUMULATE ; if not 0,
; accumulate data
DO_OLD_INT8?: ; check to see if we do old int 8
INC CS:TIMER_COUNT ; increment counter
CMP CS:TIMER_COUNT, Number_Of_Ticks
; do it this tick?
JNE SKIP_OLD_INT8 ; skip int 8
; if not time
MOV CS:TIMER_COUNT, 0 ; reset counter to
; zero
JMP CS:DWORD PTR OLD_INT8 ; jump to old
; interrupt 8
SKIP_OLD_INT8:
PUSH AX ; save ax
MOV AL, 20H ; end of interrupt
; code
OUT 20H, AL ; send eoi to 8259
POP AX ; restore ax
IRET ; return from this
; interrupt
NEW_TIMER ENDP
;------------------------------------------------------------------
ACCUMULATE PROC NEAR
; accumulate data at clock interrupt
PUSH AX ; push registers
PUSH BX
PUSH CX
PUSH BP
; check for table overflow
MOV AX, CS:MAX_OFS ; load ax
CMP CS:TABLE_OFS, AX ; have we reached
; end of table?
JAE END_ACCUM ; if so, skip
; data accumulate
; accumulate samples
MOV BX, CS:TABLE_OFS ; table address to bx
MOV BP, SP ; sp to bp
MOV AX, SS:[BP+10] ; load ax with
; interrupted ip
MOV CS:WORD PTR DATA_TABLE[BX], AX ;save ip
MOV AX, SS:[BP+12] ;load ax with
; interrupted cs
MOV CS:WORD PTR DATA_TABLE[BX+2], AX ;save cs
ADD CS:TABLE_OFS, 4 ;increment offset
; into table
END_ACCUM:
POP BP ;restore registers
POP CX
POP BX
POP AX
RET
ACCUMULATE ENDP
;-----------------------------------------------------------------;
; DATA AREA ;
;-----------------------------------------------------------------;
SUBJECT_NAME DB 'SUBJECT.COM' ;asciiz name of subject
DB 0 ;asciiz terminator
MEM_ERR_STRNG DB 'ERROR SHRINKING MEMORY - PROFILE ENDS$'
EXEC_PARAMS EQU $ ;parameters passed
ENVIRON_SEG DW ? ;to exec'ed programs
COMMND_OFS DW ?
COMMND_SEG DW ?
FCB1_OFS DW ?
FCB1_SEG DW ?
FCB2_OFS DW ?
FCB2_SEG DW ?
SAV_SP DW ? ;word to save stack pointer
; across exec's
PRINT_NAME DB 'LISTPRF.COM' ;asciiz name of data
;reduction & printout program
DB 0 ;asciiz terminator
TIMER_COUNT DW 0 ;counts timer interrupts
; since
; last jump to original
; interrupt 8
ACCUM_FLAG DW 0 ; flag to trigger address
; accumulation
OLD_INT8 EQU $ ;address of old timer interrupt
OLD_OFS DW ? ;offset of old timer interrupt
OLD_SEG DW ? ;segment of old timer interrupt
OUR_STACK DD 100H DUP (0) ;space for our stack
END_STACK EQU $ ;set sp to this offset
MAX_OFS DW Table_Size ;max offset from beginning
; of data table
TABLE_OFS DW ? ;current offset into
; data table
DATA_TABLE DB Table_Size DUP(0)
EOM EQU $ ;end of memory
PSP ENDS
;
END PRF